package com.lagou.edu.context.fatory;

import com.lagou.edu.context.MetadataReader;

import java.lang.annotation.Annotation;
import java.util.*;


/**
 * @Author zhaozuowen
 * @Description
 * @Date 2020-01-12 11:21
 **/

public class SimpleMetadataReader implements MetadataReader {

    private Class<?> classType;

    protected final Set<String> annotationSet = new LinkedHashSet<>(4);

    //@Service  key=Service value=Componet,Index
    protected final Map<String,Set<String>> metaAnnotationMap=new HashMap<>();


    public SimpleMetadataReader(Class classType) {
        this.classType =classType;
        Annotation[] annotations = classType.getAnnotations();
        for (Annotation annotation : annotations) {
            Class annotationType=annotation.annotationType();
            annotationSet.add(annotationType.getName());
            findMetaAnnotation(annotationType);

        }
    }


    //@Service
    private void findMetaAnnotation(Class annotationType){
        Set<String> annotationTypeSet = metaAnnotationMap.computeIfAbsent(annotationType.getName(), f -> new HashSet<>());
        findMetaAnnotation(annotationType, annotationTypeSet);
        metaAnnotationMap.put(annotationType.getName(),annotationTypeSet);

    }

    private void findMetaAnnotation(Class annotationType, Set<String> annotationTypeSet) {
        Annotation[] annotations = annotationType.getAnnotations();
        for (Annotation metaAnnotation : annotations) {
             if(!metaAnnotation.annotationType().getName().startsWith("java.lang.annotation")){
                 annotationTypeSet.add(metaAnnotation.annotationType().getName());
                 findMetaAnnotation(metaAnnotation.annotationType(),annotationTypeSet);
             }
        }
    }

    @Override
    public boolean hasAnnotation(String annotationName) {
        return annotationSet.contains(annotationName);
    }

    @Override
    public boolean hasMetaAnnotation(String metaAnnotationName) {
        Collection<Set<String>> values = metaAnnotationMap.values();
        for (Set<String> value : values) {
             if(value.contains(metaAnnotationName)){
                 return true;
             }
        }

        return false;
    }

    @Override
    public Class<?> getClasses() {
        return this.classType;
    }

    @Override
    public Set<String> getAnnotationSet() {
        return annotationSet;
    }


}
